# -*- coding:utf-8 -*-
# created on 2017/4/30
#

from mathsolver.functions.base import *
from mathsolver.functions.base.base import new_latex


# A是△ABC的直角顶点
class XLSanJiaoZhiJiaoDingDianUpdate(BaseFunction):
    """
    在直角△ABC中,A是△ABC的直角顶点, G是△ABC的重心,|\\overrightarrow{AB}|=2,|\\overrightarrow{AC}|=1,
    则\\overrightarrow{AG}•\\overrightarrow{BC}=
    """
    def solver(self, *args):
        assert len(args) == 2
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        zhi_jiao_ding_dian = args[1].sympify()
        sjx.Angle_Rectangular_name = str(zhi_jiao_ding_dian)
        _type = sjx.type
        sjx.get_gougudingli()
        if _type == "vIsoscelesRectangularTriangle":
            sjx.get_is_osceles_eq()
        self.output.append(sjx)
        return self


# AD为斜边BC上的高
class XLSanJiaoZhiJiaoXieBianUpdate(BaseFunction):
    def solver(self, *args):
        assert len(args) == 2
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        line_p1, line_p2 = args[1].value
        point_a_name = sjx.point_A_name
        point_b_name = sjx.point_B_name
        point_c_name = sjx.point_C_name
        zhi_jiao_ding_dian = {point_a_name, point_b_name, point_c_name} - {line_p1, line_p2}
        zhi_jiao_ding_dian = list(zhi_jiao_ding_dian)
        assert len(zhi_jiao_ding_dian) == 1
        zhi_jiao_ding_dian = zhi_jiao_ding_dian[0]
        sjx.Angle_Rectangular_name = str(zhi_jiao_ding_dian)
        _type = sjx.type
        sjx.get_gougudingli()
        if _type == "vIsoscelesRectangularTriangle":
            sjx.get_IsoscelesEq()
        self.output.append(sjx)
        return self


# AD为斜边BC上的高
class XLSanJiaoXieBianGaoUpdate(BaseFunction):
    """
    在等腰直角△ABC中,|\\overrightarrow{AB}|=4,AD为斜边BC上的高,D是BC边上一点,M为线段AD的中点,
    则\\overrightarrow{AB}•\\overrightarrow{CM} =
    """
    def solver(self, *args):
        assert len(args) == 3
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        line_p1, line_p2 = args[2].value   # 斜边
        point_a_name = sjx.point_A_name
        point_b_name = sjx.point_B_name
        point_c_name = sjx.point_C_name
        zhi_jiao_ding_dian = {point_a_name, point_b_name, point_c_name} - {line_p1, line_p2}
        zhi_jiao_ding_dian = list(zhi_jiao_ding_dian)
        assert len(zhi_jiao_ding_dian) == 1
        zhi_jiao_ding_dian = zhi_jiao_ding_dian[0]
        sjx.Angle_Rectangular_name = str(zhi_jiao_ding_dian)
        _type = sjx.type
        sjx.get_gougudingli()
        if _type == "vIsoscelesRectangularTriangle":
            sjx.get_is_osceles_eq()
        v_eqs = sjx.Eqs
        line1_p1, line1_p2 = args[1].value
        vector_a = "vector" + "(" + line1_p1 + line1_p2 + ")"
        vector_a = sympify(vector_a)
        line2_p1, line2_p2 = args[2].value
        vector_b = "vector" + "(" + line2_p1 + line2_p2 + ")"
        vector_b = sympify(vector_b)
        v_eqs.append([vector_a * vector_b, S.Zero])
        sjx.Eqs = v_eqs
        self.output.append(sjx)
        return self


# G是△ABC的重心
class XLSanJiaoZhongXinUpdate(BaseFunction):
    """
    在直角△ABC中,A是△ABC的直角顶点, G是△ABC的重心,|\\overrightarrow{AB}|=2,|\\overrightarrow{AC}|=1,
    则\\overrightarrow{AG}•\\overrightarrow{BC}=
    """
    def solver(self, *args):
        assert len(args) == 2
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        zhong_xin = args[1].sympify()
        sjx.point_Gravity_name = str(zhong_xin)
        self.output.append(sjx)
        return self


# 更新三角形方程
class XLSanJiaoEqUpdate(BaseFunction):
    def solver(self, *args):
        assert len(args) == 2
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        sjx.eq_update(args[1])
        self.output.append(sjx)
        return self


# 更新三角形方程组
class XLSanJiaoEqsUpdate(BaseFunction):
    """
    在直角△ABC中,A是△ABC的直角顶点, G是△ABC的重心,|\\overrightarrow{AB}|=2,|\\overrightarrow{AC}|=1,
    则\\overrightarrow{AG}•\\overrightarrow{BC}=
    """
    def solver(self, *args):
        assert len(args) == 2
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        sjx.eqs_update(args[1])
        self.output.append(sjx)
        return self


# AD为BC上的高
class XLSanJiaoGaoUpdate(BaseFunction):
    def solver(self, *args):
        assert len(args) == 3
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        v_eqs = sjx.Eqs
        line1_p1, line1_p2 = args[1].value
        vector_a = "vector" + "(" + line1_p1 + line1_p2 + ")"
        vector_a = sympify(vector_a)
        line2_p1, line2_p2 = args[2].value
        vector_b = "vector" + "(" + line2_p1 + line2_p2 + ")"
        vector_b = sympify(vector_b)
        v_eqs.append([vector_a * vector_b, S.Zero])
        sjx.Eqs = v_eqs
        self.output.append(sjx)
        return self


# D是BC边上一点
class XLSanJiaoDianOnLineUpdate(BaseFunction):
    """
    在边长为1的等边△ABC中,D为BC边上一动点,则\\overrightarrow{AB}•\\overrightarrow{AD}=.
    """
    def solver(self, *args):
        assert len(args) == 3
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        p = args[1].sympify()
        line_left, line_right = args[2].value
        vector_a = "vector" + "(" + line_left + str(p) + ")"
        vector_a = sympify(vector_a)
        vector_b = "vector" + "(" + str(p) + line_right + ")"
        vector_b = sympify(vector_b)
        v_eqs = sjx.Eqs
        v_eqs.append([vector_a, sympify('t1') * vector_b])
        v_eqs.append([sympify('t1'), ">", S.Zero])
        sjx.Eqs = v_eqs
        line_name = str(line_left) + str(line_right)
        self.steps.append(["", "∵ 点%s在%s上" % (new_latex(p), new_latex(line_name))])
        self.steps.append(["", "∴ %s" % BaseEq([vector_a, sympify('t1') * vector_b]).printing()])
        self.output.append(sjx)
        return self


# M为线段AD的中点
class XLSanJiaoZhongDianUpdate(BaseFunction):
    """
    在直角△ABC中,点D是斜边AB的中点,点P为线段CD的中点,
    则\\dfrac{|\\overrightarrow{PA}|^2+|\\overrightarrow{PB}|^2}{|\\overrightarrow{PC}|^2}=()
    """
    def solver(self, *args):
        assert len(args) == 3
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        p = args[1].sympify()
        line_left, line_right = args[2].value
        vector_a = "vector" + "(" + line_left + str(p) + ")"
        vector_a = sympify(vector_a)
        vector_b = "vector" + "(" + str(p) + line_right + ")"
        vector_b = sympify(vector_b)
        v_eqs = sjx.Eqs
        v_eqs.append([vector_a, vector_b])
        sjx.Eqs = v_eqs
        self.output.append(sjx)
        return self


# 更新等边三角形边长
class XLRegularTriangleLengthUpdate(BaseFunction):
    """
    在边长为1的等边△ABC中,D为BC边上一动点,则\\overrightarrow{AB}•\\overrightarrow{AD}=.
    """
    def solver(self, *args):
        assert len(args) == 2
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        edge_length = args[1].sympify()
        if edge_length.free_symbols:
            v_eqs = sjx.Eqs
            v_eqs.append([edge_length, ">", S.Zero])
            sjx.Eqs = v_eqs
        sjx.edge_length = edge_length
        self.output.append(sjx)
        return self


# 更新三角形面积
class XLSanJiaoAreaUpdate(BaseFunction):
    """
    在等边△ABC中,\\overrightarrow{AC}=2\\overrightarrow{AD},△ABC的面积为6\\sqrt{6}.
    若\\overrightarrow{AP}=\\frac{1}{2}\\overrightarrow{AC}+\\frac{5}{6}\\overrightarrow{AB},则△ABP的面积为
    """
    def solver(self, *args):
        assert len(args) == 2
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        area = args[1].sympify()
        sjx.Area = area
        sjx.get_area_eq()
        self.output.append(sjx)
        return self


# 更新三角形外接圆圆心-外心
class XLSanJiaoWaiXinUpdate(BaseFunction):
    def solver(self, *args):
        assert len(args) == 2
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        if isinstance(args[1], BasePoint):
            wai_xin = args[1].name
        else:
            wai_xin = args[1].sympify()
        sjx.point_Waixin_name = str(wai_xin)
        sjx.get_waibanjing_eqs()
        self.output.append(sjx)
        return self


# 更新三角形外接圆半径
class XLSanJiaoWaiBanJingUpdate(BaseFunction):
    def solver(self, *args):
        assert len(args) == 2
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        wai_ban_jing = args[1].sympify()
        v_eqs = sjx.Eqs
        if wai_ban_jing.free_symbols:
            v_eqs.append([wai_ban_jing, ">", S.Zero])
        sjx.WaiBanJing_value = wai_ban_jing
        sjx.Eqs = v_eqs
        point_waixin_name = sjx.point_Waixin_name
        point_a_name = sjx.point_A_name
        point_b_name = sjx.point_B_name
        point_c_name = sjx.point_C_name
        vector_1 = "vector" + "(" + point_waixin_name + point_a_name + ")"
        vector_1 = sympify(vector_1)
        vector_2 = "vector" + "(" + point_waixin_name + point_b_name + ")"
        vector_2 = sympify(vector_2)
        vector_3 = "vector" + "(" + point_waixin_name + point_c_name + ")"
        vector_3 = sympify(vector_3)
        v_eqs.append([vector_1 * vector_1, wai_ban_jing ** 2])
        v_eqs.append([vector_2 * vector_2, wai_ban_jing ** 2])
        v_eqs.append([vector_3 * vector_3, wai_ban_jing ** 2])
        sjx.Eqs = v_eqs
        self.output.append(sjx)
        return self


# \\angle ABC=60°
class XLSanJiaoGeoEqUpdate(BaseFunction):
    def solver(self, *args):
        assert len(args) == 2
        p1, p2, p3 = args[0].value
        name = p1 + p2 + p3
        assert name in self.known
        sjx = self.search(name)
        assert sjx
        eq_left = sympify(args[1].value[0])
        eq_right = sympify(args[1].value[1])
        assert str(eq_left.func) == str("Angle")
        assert str(eq_right.func) == str("d")
        if len(eq_left.args) == 3:
            angle_name = eq_left.args[1]
        else:
            angle_name = eq_left.args[0]
        angle_value = eq_right.args[0] / 180 * pi
        if str(angle_name) == sjx.point_A_name:
            sjx.Angle_A_value = angle_value
        elif str(angle_name) == sjx.point_B_name:
            sjx.Angle_B_value = angle_value
        elif str(angle_name) == sjx.point_C_name:
            sjx.Angle_C_value = angle_value
        elif str(angle_name) == sjx.point_D_name:
            sjx.Angle_D_value = angle_value
        else:
            raise 'try fail'
        if sjx.type == "vRectangularTriangle" or sjx.type == "vIsoscelesRectangularTriangle":
            if sjx.Angle_A_value == pi / 2:
                sjx.Angle_Rectangular_name = sjx.point_A_name
            elif sjx.Angle_B_value == pi / 2:
                sjx.Angle_Rectangular_name = sjx.point_B_name
            elif sjx.Angle_B_value == pi / 2:
                sjx.Angle_Rectangular_name = sjx.point_C_name
        self.output.append(sjx)
        return self
